# -*- coding: utf-8 -*-

import json

from django.conf import settings
from sqlalchemy import func

from analysis.games.es import query_game_orders
from common import orm
from common.lottery import METIS_GAME_TYPE, GAME_TYPE
from common.cache import redis_cache
from common.platform.common.model import PLATFORM_TYPE, MetisPlatformUser, metis_orm, MetisPlatformLogBet
from common.platform.metis.model import (MetisBetLogs, MetisGamePart,
                                         MetisGameTerm, MetisPool)
from common.platform.metis import metis_api
from common.stats import MG_BIGBANG_COLL as mg
from common.utils import track_logging, tz
from common.utils.currency import convert_fen_to_yuan, convert_yuan_to_fen
from common.utils.db import list_object, paginate
from common.utils.decorator import sql_wrapper
from common.account.db.account import get_account
from common.utils.tz import (date_str_before, local_now, local_str_to_utc_str,
                             now_ts, to_ts, today_str,
                             ts_to_local_datetime_str)

_LOGGER = track_logging.getLogger(__name__)


def add_bet_logs(data):
    log = MetisBetLogs()
    log.ticket_id = data['id']
    log.user_id = data['user_id']
    log.status = False
    log.game_id = data['game_id']
    log.bet_type = data['bet_type']
    log.bet_amount = convert_yuan_to_fen(data['bet_amount'])
    log.bet_result = convert_yuan_to_fen(data['bet_result'])
    log.round_id = data['round_id']
    log.extend = data['memo']
    notes = json.loads(data['notes']) if data['notes'] else {}
    log.both_press = notes.get('both_press', False)
    extend = json.loads(data['memo'])
    bet_index = []
    if data['game_id'] == METIS_GAME_TYPE.FUNK_MONKEY:
        bet_index = 0
    else:
        for i in extend['bet_list']:
            bet_index.append(i['bet_section_index'])
        bet_index = ','.join(str(s) for s in list(set(bet_index)))
    log.play_type = bet_index
    log.create_time = local_str_to_utc_str(data['created_at'])
    log.save(auto_commit=False)
    orm.session.flush()
    return log.as_dict()


def cretate_game_term(data):
    term = MetisGameTerm.query.filter(MetisGameTerm.round_id == data['round_id']).first()
    if not term:
        term = MetisGameTerm()
        term.game_id = data['game_id']
        term.ticket_id = data['id']
        term.round_id = data['round_id']  # 唯一，一局只有一个局号
        term.extend = data['memo']
        term.total_people = 1
        term.total_bet_amount = convert_yuan_to_fen(data['bet_amount'])
        term.total_bet_result = convert_yuan_to_fen(data['bet_result'])
        extend = json.loads(data['memo'])
        term.cards = json.dumps(extend['hand_card_list'])
        term.create_time = local_str_to_utc_str(data['created_at'])
        term.save(auto_commit=False)
    else:
        term.total_people += 1
        term.total_bet_amount += convert_yuan_to_fen(data['bet_amount'])
        term.total_bet_result += convert_yuan_to_fen(data['bet_result'])
        term.save(auto_commit=False)


def cretate_game_part(data):
    d = json.loads(data['memo'])
    for idx, val in enumerate(d['section_bet_money']):
        if val:
            part = MetisGamePart()
            part.game_id = data['game_id']
            part.ticket_id = data['id']
            part.round_id = data['round_id']
            part.user_id = data['user_id']
            part.bet_index = idx
            part.bet_amount = convert_yuan_to_fen(d['section_bet_money'][idx])
            part.bet_result = convert_yuan_to_fen(d['section_bet_result'][idx])
            part.extend = data['memo']
            part.create_time = local_str_to_utc_str(data['created_at'])
            part.save(auto_commit=False)


def get_ticketid_for_betlogs(game_id):
    query = MetisBetLogs.query.filter(MetisBetLogs.game_id == game_id).order_by(
        MetisBetLogs.ticket_id.desc()).first()
    return query.ticket_id if query else None


def get_bet_logs_by_user_id(user_id, start_created_at=None, end_created_at=None, page=1, size=30):
    query = query_game_orders(user_id=user_id,
                              start_created_at=start_created_at,
                              end_created_at=end_created_at,
                              page=page, page_size=size)
    resp = []
    for item in query['orders']:
        # 是否把游戏类型,用户名等同步到es？
        info = {}
        info['user_id'] = item['user_id']
        info['user_name'] = get_account(info['user_id'], use_cache=True).user_name
        info['bet_amount'] = convert_fen_to_yuan(item['bet_amount'])
        info['bet_result'] = convert_fen_to_yuan(item['bet_result'])
        info['game_id'] = item['game_id']
        info['platform'] = PLATFORM_TYPE.get_label(item['platform_type'])
        if info['platform'] == 'metis':
            info['game_title'] = METIS_GAME_TYPE.get_label(item['game_id'])
        elif info['platform'] == 'witch':
            info['game_title'] = GAME_TYPE.get_label(item['game_id'])

        info['create_time'] = ts_to_local_datetime_str(item['created_at'])
        resp.append(info)
    return resp


@sql_wrapper
def list_all_orders(query_dct):
    query, total_count = list_object(query_dct, MetisBetLogs, disable_paginate=True)
    total_bet = query.with_entities(func.sum(MetisBetLogs.bet_amount)).scalar() or 0
    total_win = query.with_entities(func.sum(MetisBetLogs.bet_result)).scalar() or 0
    query = paginate(query, query_dct)
    return query.all(), total_count, total_bet, total_win


def calculate_accumulated_win_amount(user_id, start_time, end_time):
    """
    计算时间段用户的派奖总
    """
    if settings.IS_PRODUCTION_ENV:
        try:
            metis_user_id = MetisPlatformUser.query.filter(MetisPlatformUser.subsidiary_user_id == user_id).first().id
            amount = metis_orm.session.query(
                func.sum(MetisPlatformLogBet.bet_amount) + func.sum(MetisPlatformLogBet.bet_result)).filter(
                MetisPlatformLogBet.user_id == metis_user_id,
                MetisPlatformLogBet.created_at > tz.utc_to_local(start_time),
                MetisPlatformLogBet.created_at <= tz.utc_to_local(end_time),
                MetisPlatformLogBet.bet_type != 0,
                MetisPlatformLogBet.bet_result > 0).scalar() or 0
            amount = int(amount * 100)
        finally:
            metis_orm.session.close()
    else:
        amount = orm.session.query(
            func.sum(MetisBetLogs.bet_amount) + func.sum(MetisBetLogs.bet_result)).filter(
            MetisBetLogs.user_id == user_id,
            MetisBetLogs.create_time > start_time,
            MetisBetLogs.create_time <= end_time,
            MetisBetLogs.bet_result > 0).with_hint(
            MetisBetLogs, 'USE INDEX(user_id)').scalar() or 0
    return amount


@sql_wrapper
def list_metis_game(query_dct, game_id):
    query_dct['game_id'] = game_id
    return list_object(query_dct, MetisGameTerm)


@sql_wrapper
def list_metis_game_part(query_dct, game_id):
    query_dct['game_id'] = game_id
    query, total_count = list_object(query_dct, MetisGamePart, disable_paginate=True)
    total_bet = query.with_entities(func.sum(MetisGamePart.bet_amount)).scalar() or 0
    total_win = query.with_entities(func.sum(MetisGamePart.bet_result)).scalar() or 0
    query = paginate(query, query_dct)
    return query.all(), total_count, total_bet, total_win


def add_pool(game_id, control_rate, control_pool, now_rate, now_pool):
    water_rate, water_pool = get_pool(game_id, today_str())
    pool = MetisPool()
    pool.game_id = game_id
    pool.date = date_str_before()
    pool.water_rate = water_rate
    pool.water_pool = water_pool
    pool.control_rate = control_rate
    pool.control_pool = control_pool
    pool.now_rate = now_rate
    pool.now_pool = now_pool
    pool.save()
    return {'now_rate': now_rate, 'now_pool': now_pool}


def get_pool(game_id, date):
    query = MetisPool.query.filter(MetisPool.game_id == game_id).filter(
        MetisPool.date == date).order_by(
        MetisPool.created_at.desc()).first()
    if query:
        return float(query.now_rate), float(query.now_pool)
    status, data = metis_api.get_pool(game_id)
    if status:
        return float(data['pool_refund']), float(data['pool_money'])
    return 0, 0


def is_over_daily_bet(user_id):
    """判断是否有超出单日投注上限"""
    daily_stats = mg.daily_stats.find_one({"_id": "%s-%s" % (
        user_id, local_now().strftime('%Y-%m-%d'))}) or {}
    metis_report = daily_stats.get('metis') or {}
    user_bet = metis_report.get('total_bet', 0)
    limit_bet = redis_cache.get_daily_bet('metis')
    if float(user_bet) >= float(limit_bet):
        return True
    return False


def is_black_user(user_id):
    """判断是否为黑名单用户"""
    uids = redis_cache.get_metis_risk_uids('metis', 'forbidden')
    if str(user_id) in uids:
        return True
    return False


def is_pass_user(user_id):
    """ metis白名单 """
    uids = redis_cache.get_metis_risk_uids('metis', 'pass')
    if len(uids) != 0 and str(user_id) not in uids:
        return True
    return False
